
/**
 * @file xxx
 * @brief Declaration file of typename xxx.
 *
 * This file includes the declaration of typename xxx, and
 * the definitions of the macros, struct, enum and so on.
 *
 * @attention used for C++ only.
 */



#ifndef __cplusplus
#    error ERROR: This file requires C++ compilation (use a .cpp suffix)
#endif


#ifndef TRAITS_H
#define TRAITS_H

#include <tuple>

template <typename T>
struct TypeTraits
{
    typedef T type_value;
    typedef T& refType_value;
    typedef const T& constRefType_value;
    typedef T* pointerType_value;
    typedef const T* constPointerType_value;
};

//>>>
template <typename Re>
struct ParameterTraits
{
    static const int size = -1;
};

template <typename Re>
struct ParameterTraits<Re (*)()>
{
    static const int size = 0;
};

template <typename Re, typename T0>
struct ParameterTraits<Re (*)(T0)>
{
    static const int size = 1;
    typedef T0 P0;
};

template <typename Re, typename T0, typename T1>
struct ParameterTraits<Re (*)(T0, T1)>
{
    static const int size = 2;
    typedef T0 P0;
    typedef T1 P1;
};

template <typename Re, typename T0, typename T1, typename T2>
struct ParameterTraits<Re (*)(T0, T1, T2)>
{
    static const int size = 3;
    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
};

template <typename Re, typename T0, typename T1, typename T2, typename T3>
struct ParameterTraits<Re (*)(T0, T1, T2, T3)>
{
    static const int size = 4;
    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
    typedef T3 P3;
};

template <typename Re, typename T0, typename T1, typename T2, typename T3, typename T4>
struct ParameterTraits<Re (*)(T0, T1, T2, T3, T4)>
{
    static const int size = 5;
    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
    typedef T3 P3;
    typedef T4 P4;
};

template <typename Re, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
struct ParameterTraits<Re (*)(T0, T1, T2, T3, T4, T5)>
{
    static const int size = 6;
    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
    typedef T3 P3;
    typedef T4 P4;
    typedef T5 P5;
};

template <typename Re, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
struct ParameterTraits<Re (*)(T0, T1, T2, T3, T4, T5, T6)>
{
    static const int size = 7;
    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
    typedef T3 P3;
    typedef T4 P4;
    typedef T5 P5;
    typedef T6 P6;
};

template <typename Re, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
          typename T7>
struct ParameterTraits<Re (*)(T0, T1, T2, T3, T4, T5, T6, T7)>
{
    static const int size = 8;
    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
    typedef T3 P3;
    typedef T4 P4;
    typedef T5 P5;
    typedef T6 P6;
    typedef T7 P7;
};

template <typename Re, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
          typename T7, typename T8>
struct ParameterTraits<Re (*)(T0, T1, T2, T3, T4, T5, T6, T7, T8)>
{
    static const int size = 9;
    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
    typedef T3 P3;
    typedef T4 P4;
    typedef T5 P5;
    typedef T6 P6;
    typedef T7 P7;
    typedef T8 P8;
};

template <typename Re, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
          typename T7, typename T8, typename T9>
struct ParameterTraits<Re (*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)>
{
    static const int size = 10;
    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
    typedef T3 P3;
    typedef T4 P4;
    typedef T5 P5;
    typedef T6 P6;
    typedef T7 P7;
    typedef T8 P8;
    typedef T9 P9;
};



//>>>>
template <typename Class, typename Re>
struct ParameterTraits<Re (Class::*)()>
{
    static const int size = 0;

    typedef Class classType_value;

};

template <typename Class, typename Re, typename T0>
struct ParameterTraits<Re (Class::*)(T0)>
{
    static const int size = 1;

    typedef T0 P0;

    typedef Class classType_value;

};

template <typename Class, typename Re, typename T0, typename T1>
struct ParameterTraits<Re (Class::*)(T0, T1)>
{
    static const int size = 2;

    typedef T0 P0;
    typedef T1 P1;

    typedef Class classType_value;
};

template <typename Class, typename Re, typename T0, typename T1, typename T2>
struct ParameterTraits<Re (Class::*)(T0, T1, T2)>
{
    static const int size = 3;

    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;

    typedef Class classType_value;
};

template <typename Class, typename Re, typename T0, typename T1, typename T2, typename T3>
struct ParameterTraits<Re (Class::*)(T0, T1, T2, T3)>
{
    static const int size = 4;

    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
    typedef T3 P3;

    typedef Class classType_value;
};

template <typename Class, typename Re, typename T0, typename T1, typename T2, typename T3, typename T4>
struct ParameterTraits<Re (Class::*)(T0, T1, T2, T3, T4)>
{
    static const int size = 5;

    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
    typedef T3 P3;
    typedef T4 P4;

    typedef Class classType_value;
};

template <typename Class, typename Re, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
struct ParameterTraits<Re (Class::*)(T0, T1, T2, T3, T4, T5)>
{
    static const int size = 6;

    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
    typedef T3 P3;
    typedef T4 P4;
    typedef T5 P5;

    typedef Class classType_value;
};

template <typename Class, typename Re, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6>
struct ParameterTraits<Re (Class::*)(T0, T1, T2, T3, T4, T5, T6)>
{
    static const int size = 7;

    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
    typedef T3 P3;
    typedef T4 P4;
    typedef T5 P5;
    typedef T6 P6;

    typedef Class classType_value;
};

template <typename Class, typename Re, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7>
struct ParameterTraits<Re (Class::*)(T0, T1, T2, T3, T4, T5, T6, T7)>
{
    static const int size = 8;

    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
    typedef T3 P3;
    typedef T4 P4;
    typedef T5 P5;
    typedef T6 P6;
    typedef T7 P7;

    typedef Class classType_value;
};

template <typename Class, typename Re, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7, typename T8>
struct ParameterTraits<Re (Class::*)(T0, T1, T2, T3, T4, T5, T6, T7, T8)>
{
    static const int size = 9;

    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
    typedef T3 P3;
    typedef T4 P4;
    typedef T5 P5;
    typedef T6 P6;
    typedef T7 P7;
    typedef T8 P8;

    typedef Class classType_value;
};

template <typename Class, typename Re, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7, typename T8, typename T9>
struct ParameterTraits<Re (Class::*)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)>
{
    static const int size = 10;

    typedef T0 P0;
    typedef T1 P1;
    typedef T2 P2;
    typedef T3 P3;
    typedef T4 P4;
    typedef T5 P5;
    typedef T6 P6;
    typedef T7 P7;
    typedef T8 P8;
    typedef T9 P9;

    typedef Class classType_value;
};


//>>>
template<int Size, typename T>
struct ParameterTupleTraitsProxy
{

};

template<typename T>
struct ParameterTupleTraitsProxy<0, T>
{
    typedef std::tuple<> Parameters;
};

template<typename T>
struct ParameterTupleTraitsProxy<1, T>
{
    typedef std::tuple<typename T::P0> Parameters;
};

template<typename T>
struct ParameterTupleTraitsProxy<2, T>
{
    typedef std::tuple<typename T::P0, typename T::P1> Parameters;
};

template<typename T>
struct ParameterTupleTraitsProxy<3, T>
{
    typedef std::tuple<typename T::P0, typename T::P1, typename T::P2> Parameters;
};

template<typename T>
struct ParameterTupleTraitsProxy<4, T>
{
    typedef std::tuple<typename T::P0, typename T::P1,
                       typename T::P2, typename T::P3> Parameters;
};

template<typename T>
struct ParameterTupleTraitsProxy<5, T>
{
    typedef std::tuple<typename T::P0, typename T::P1,
                       typename T::P2, typename T::P3,
                       typename T::P4> Parameters;
};

template<typename T>
struct ParameterTupleTraitsProxy<6, T>
{
    typedef std::tuple<typename T::P0, typename T::P1,
                       typename T::P2, typename T::P3,
                       typename T::P4, typename T::P5> Parameters;
};


template<typename T>
struct ParameterTupleTraitsProxy<7, T>
{
    typedef std::tuple<typename T::P0, typename T::P1,
                       typename T::P2, typename T::P3,
                       typename T::P4, typename T::P5,
                       typename T::P6> Parameters;
};

template<typename T>
struct ParameterTupleTraitsProxy<8, T>
{
    typedef std::tuple<typename T::P0, typename T::P1,
                       typename T::P2, typename T::P3,
                       typename T::P4, typename T::P5,
                       typename T::P6, typename T::P7> Parameters;
};

template<typename T>
struct ParameterTupleTraitsProxy<9, T>
{
    typedef std::tuple<typename T::P0, typename T::P1,
                       typename T::P2, typename T::P3,
                       typename T::P4, typename T::P5,
                       typename T::P6, typename T::P7,
                       typename T::P8> Parameters;
};

template<typename T>
struct ParameterTupleTraitsProxy<10, T>
{
    typedef std::tuple<typename T::P0, typename T::P1,
                       typename T::P2, typename T::P3,
                       typename T::P4, typename T::P5,
                       typename T::P6, typename T::P7,
                       typename T::P8, typename T::P9> Parameters;
};


template <typename ParameterTraits>
struct ParameterTupleTraits
{
    typedef typename ParameterTupleTraitsProxy<ParameterTraits::size, ParameterTraits>::Parameters Parameters;
};
























#endif // TRAITS_H
